﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using com.huigo.Framework.ServiceUtils;
using System.Xml;
using com.huigo.B2B.Web.alipay;
using System.IO;

namespace com.huigo.B2B.Web
{
    public class PayService
    {
        public static bool Invoke(PayInfo payInfo)
        {
            bool isSuccess = false;
            if (payInfo != null)
            {
                payInfo.OrderId = PayService.GetOrderId(payInfo.PayId);
                payInfo.OrderName = PayService.GetOrderName(payInfo.PayId, payInfo.PayNo);
                //switch (payInfo.PayFor)
                //{
                //    case (int)Dict.PayFor.ORDER:
                //    case (int)Dict.PayFor.INVOICE:
                //        isSuccess = InvokePay(payInfo);
                //        break;
                //    case (int)Dict.PayFor.SUPPLEMENT:
                //        isSuccess = InvokeSupplement(payInfo);
                //        break;
                //}
                if (!IsOrderIdExisted(payInfo.OrderId))
                {
                    isSuccess = InsertPayInfo(payInfo);
                }
            }
            return isSuccess;
        }

        private static bool InsertPayInfo(PayInfo payInfo)
        {
            try
            {
                List<RequestFuncParams> list = new List<RequestFuncParams>();
                list.Add(new RequestFuncParams("initCustFid", payInfo.CustId.ToString()));
                list.Add(new RequestFuncParams("initType", payInfo.PayNo == string.Empty ? ((int)Dict.FeeType.SUPPLEMENT).ToString() : ((int)Dict.FeeType.CONSUME).ToString()));
                list.Add(new RequestFuncParams("initFor", payInfo.PayFor.ToString()));
                list.Add(new RequestFuncParams("initRelatedFid", payInfo.PayId.ToString()));
                list.Add(new RequestFuncParams("initChannel", payInfo.PayType));
                list.Add(new RequestFuncParams("initChangeFee", payInfo.Fee.ToString()));
                list.Add(new RequestFuncParams("initPayFee", payInfo.TotalFee.ToString()));
                list.Add(new RequestFuncParams("initOutPayNo", payInfo.OrderId));
                list.Add(new RequestFuncParams("initOutPayDesc", payInfo.OrderName));
                BaseService service = new BaseService();
                ParserXml parser = service.RequestEntryService(Dict.ERequestFunc.ADD_INVOKE, list);
                if (parser != null && parser.RowsCount > 0 && parser["returnargs", 0] == "true")
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception err)
            {
                //Log.WritePayLog("在fore_trade_info中插入一条数据&在fee_flow中插入一条充值信息一条消费信息,ProductId:" + payInfo.ProductId.ToString() + "，错误信息：" + err.Message + "，出错位置：PayService.InsertPayInfo(PayInfo payInfo,1)" + ",用户名:" + GetUsername());
                return false;
            }
        }

        private static bool IsOrderIdExisted(string orderId)
        {
            List<RequestFuncParams> list = new List<RequestFuncParams>();
            list.Add(new RequestFuncParams("orderId", orderId));
            BaseService service = new BaseService();
            ParserXml parser = service.RequestEntryService(Dict.ERequestFunc.GET_INVOKE_BY_ORDER_ID, list);
            if (parser != null && parser.RowsCount > 0)
            {
                return true;
            }
            return false;
        }

        public static string GetOrderId(long payId)
        {
            string orderId = string.Empty;
            Random r = new Random();
            switch (payId % 1000)
            {
                case 6://订单
                    orderId = DateTime.Now.ToString("yyyyMMddhhmmssffff") + payId.ToString();
                    break;
                case 7://发票申领
                    orderId = DateTime.Now.ToString("yyyyMMddhhmmssffff") + payId.ToString();
                    break;
                default://充值
                    orderId = DateTime.Now.ToString("yyyyMMddhhmmssffff") + r.Next(10000, 999999).ToString() + "18";
                    break;
            }
            return orderId;

        }

        public static string GetOrderName(long payId, string payNo)
        {
            string orderName = string.Empty;
            switch (payId % 1000)
            {
                case 6://订单
                    orderName = "订单支付：" + payNo; ;
                    break;
                case 7://发票申领
                    orderName = "发票申领订单支付：" + payNo; ;
                    break;
                default://充值
                    orderName = "充值";
                    break;
            }
            return orderName;
        }

        public static PayInfo InsertAlipay(string out_trade_no, string trade_no)
        {
            string res = AlipayQuery.Query(out_trade_no, trade_no);

            string defualtDate = DateTime.Now.ToString("yyyy-MM-dd");

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(res);
            //string returnIsSuc, string returnBuyerEmail, string returnBuyerId, string returnSellerEmail, string returnSellerId, string returnOutPayNo, decimal returnAmount, DateTime returnCreateTime, DateTime returnPayTime, string returnPayNo, string returnTradeStatus, string returnParams, decimal returnRefundFee, string returnRefundId, DateTime returnRefundTime, string returnRefundStatus
            List<RequestFuncParams> list = new List<RequestFuncParams>();
            list.Add(new RequestFuncParams("returnIsSuc", xmlDoc.SelectSingleNode("/alipay/is_success").InnerText));
            list.Add(new RequestFuncParams("returnBuyerEmail", (!xmlDoc.InnerXml.ToString().Contains("buyer_email")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/buyer_email").InnerText));
            list.Add(new RequestFuncParams("returnBuyerId", (!xmlDoc.InnerXml.ToString().Contains("buyer_id")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/buyer_id").InnerText));
            list.Add(new RequestFuncParams("returnSellerEmail", (!xmlDoc.InnerXml.ToString().Contains("seller_email")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/seller_email").InnerText));
            list.Add(new RequestFuncParams("returnSellerId", (!xmlDoc.InnerXml.ToString().Contains("seller_email")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/seller_email").InnerText));
            list.Add(new RequestFuncParams("returnOutPayNo", (!xmlDoc.InnerXml.ToString().Contains("out_trade_no")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/out_trade_no").InnerText));
            list.Add(new RequestFuncParams("returnAmount", (!xmlDoc.InnerXml.ToString().Contains("total_fee")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/total_fee").InnerText));
            list.Add(new RequestFuncParams("returnCreateTime", (!xmlDoc.InnerXml.ToString().Contains("gmt_create")) ? defualtDate : xmlDoc.SelectSingleNode("/alipay/response/trade/gmt_create").InnerText));
            list.Add(new RequestFuncParams("returnPayTime", (!xmlDoc.InnerXml.ToString().Contains("gmt_payment")) ? defualtDate : xmlDoc.SelectSingleNode("/alipay/response/trade/gmt_payment").InnerText));
            list.Add(new RequestFuncParams("returnPayNo", (!xmlDoc.InnerXml.ToString().Contains("trade_no")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/trade_no").InnerText));
            list.Add(new RequestFuncParams("returnTradeStatus", (!xmlDoc.InnerXml.ToString().Contains("trade_status")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/trade_status").InnerText));
            list.Add(new RequestFuncParams("returnParams", xmlDoc.InnerXml.ToString()));
            list.Add(new RequestFuncParams("returnRefundFee", (!xmlDoc.InnerXml.ToString().Contains("refund_fee")) ? "0" : xmlDoc.SelectSingleNode("/alipay/response/trade/refund_fee").InnerText));
            list.Add(new RequestFuncParams("returnRefundId", (!xmlDoc.InnerXml.ToString().Contains("refund_id")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/refund_id").InnerText));
            list.Add(new RequestFuncParams("returnRefundTime", (!xmlDoc.InnerXml.ToString().Contains("gmt_refund")) ? defualtDate : xmlDoc.SelectSingleNode("/alipay/response/trade/gmt_refund").InnerText));
            list.Add(new RequestFuncParams("returnRefundStatus", (!xmlDoc.InnerXml.ToString().Contains("refund_status")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/refund_status").InnerText));
            BaseService service = new BaseService();
            ParserXml parser = service.RequestEntryService(Dict.ERequestFunc.ADD_ALIPAY_RETURN, list);
            if (parser != null && parser.RowsCount > 0 && parser["returnargs", 0] == "true")
            {
                PayInfo payInfo = new PayInfo();
                payInfo.TotalFee = Convert.ToDecimal(xmlDoc.SelectSingleNode("/alipay/response/trade/total_fee").InnerText);
                payInfo.OrderId = out_trade_no;
                payInfo.TradeNo = trade_no;
                payInfo.OrderName = (!xmlDoc.InnerXml.ToString().Contains("body")) ? "" : xmlDoc.SelectSingleNode("/alipay/response/trade/body").InnerText;
                payInfo.PayStatus = Dict.PaymentStatus.SUC;
                payInfo.PayType = Dict.PayType.ALIPAY.ToString();
                payInfo.TradeTime = Convert.ToDateTime(xmlDoc.SelectSingleNode("/alipay/response/trade/gmt_payment").InnerText);
                return payInfo;
            }
            else
            {
                return null;
            }
        }

        public static bool ReturnSupplement(PayInfo payInfo)
        {
            bool isSuccess = false;
            System.IO.StreamWriter writer = null;
            try
            {
                string queuePath = HttpContext.Current.Request.MapPath("/queue/" + payInfo.PayId + ".txt");
                if (File.Exists(queuePath))
                {
                    System.Threading.Thread.Sleep(2000);
                }
                else
                {
                    writer = new System.IO.StreamWriter(queuePath, true);
                    writer.Write(payInfo.PayId);
                }
                if (payInfo != null && payInfo.PayStatus == Dict.PaymentStatus.SUC)
                {
                    List<RequestFuncParams> list = new List<RequestFuncParams>();
                    list.Add(new RequestFuncParams("orderId", payInfo.OrderId));
                    list.Add(new RequestFuncParams("tradeNo", payInfo.TradeNo));
                    list.Add(new RequestFuncParams("fee", payInfo.TotalFee.ToString()));
                    list.Add(new RequestFuncParams("channel", payInfo.PayType));
                    list.Add(new RequestFuncParams("payTime", payInfo.TradeTime.ToString()));
                    BaseService service = new BaseService();
                    ParserXml parser = service.RequestEntryService(Dict.ERequestFunc.PAY_SUC, list);
                    if (parser != null && parser.RowsCount > 0 && parser["returnargs", 0] == "true")
                    {
                        isSuccess = true;
                    }
                }
                if (writer != null)
                {
                    writer.Flush();
                    writer.Close();
                }
                if (File.Exists(queuePath))
                {
                    File.Delete(queuePath);
                }
            }
            catch (Exception err)
            {
                //Log.WritePayLog("接收到第三方传回的信息,ProductId:" + payInfo.ProductId.ToString() + "，错误信息：" + err.Message + "，出错位置：PayService.ReturnSupplement(PayInfo payInfo)" + ",用户名:" + GetUsername());
                return isSuccess;
            }
            finally
            {
                if (writer != null)
                {
                    writer = null;
                }
            }
            return isSuccess;
        }

    }
}
